﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace JwtMinimalDemo.Controllers
{
    [ApiController]
    public class AuthContraller : ControllerBase
    {
        [HttpPost("login")]
        public IResult Login(LoginRequest req)
        {
            var jwtIssuer = "JwtMinimalDemo";
            var jwtAudience = "JwtMinimalDemoAudience";
            var jwtSecretKey = "ThisIsASecretKey_ForDemoOnly_DoNotUseInProduction_ChangeMe!"; // >= 32 chars recommended
            var tokenLifetimeMinutes = 30; // 你选择的是 A -> 30 分钟

            var users = new[]
            {
                new {UserName="admin",Password="123456",Roles=new []{"Admin"}},
                new {UserName="user",Password="123456",Roles=new []{"User"}}
            };

            var found = users.FirstOrDefault(x => x.UserName == req.Username && x.Password == req.Password);
            if (found == null) return Results.Unauthorized();//401 未认证

            // Claims
            var claims = new List<Claim>
            {
                new Claim(JwtRegisteredClaimNames.Sub, found.UserName),
                new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
                new Claim("username", found.UserName)
            };

            // roles -> claims
            foreach (var role in found.Roles)
            {
                claims.Add(new Claim(ClaimTypes.Role, role));
            }

            // 生成token
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecretKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expires = DateTime.UtcNow.AddMinutes(tokenLifetimeMinutes);

            var token = new JwtSecurityToken(
                issuer: jwtIssuer,
                audience: jwtAudience,
                claims: claims,
                expires: expires,
                signingCredentials: creds);
            var tokenString = new JwtSecurityTokenHandler().WriteToken(token);

            return Results.Ok(new
            {
                access_token = tokenString,
                token_type = "Bearer",
                expires_at = expires.ToString("o")//  ISO 8601
            });
        }
    }

    public class LoginRequest
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}
